import base64
import hashlib
import hmac
import time
import urllib.parse
import requests
import requests.auth
import sys
import json

from coin.exchange.base.kr_rest.auth_base import AuthKey
from coin2.api_client.common import (SyncQueryer)
from enum import Enum

class Type(Enum):
  BID = "bid"
  ASK = "ask"

class BithumbAuth(requests.auth.AuthBase):
  def __init__(self, key):
    self._key = AuthKey.from_file(key)

  def __call__(self, req: requests.PreparedRequest):
    endpoint = urllib.parse.urlparse(req.url).path
    nonce = str(int(round(time.time() * 1000)))
    body = req.body
    if body is None:
      body = ""
    hmac_data = (endpoint + ';' + body + ';' + nonce).encode()
    hmh = hmac.new(self._key.secret_key_bytes, hmac_data, hashlib.sha512)
    api_sign = base64.b64encode(hmh.hexdigest().encode()).decode()

    headers = {
      'Api-Key': self._key.access_key,
      'Api-Sign': api_sign,
      'Api-Nonce': nonce,
      "api-client-type": "2",
      "Accept": "application/json",
      "Content-Type": "application/x-www-form-urlencoded",
    }
    req.headers.update(headers)
    req.prepare_headers(req.headers)

    # print(req.url)
    # print(req.headers)
    # print(req.body)

    return req

class BithumbPrivateClient():
  def __init__(self, key, mea, ip=None, proxies=None):
    self._auth = BithumbAuth(key)
    self._mea = mea
    if mea == "Spot.Bithumb.v2":
      self._url = 'https://api.bithumb.com'
    else:
      assert(0)

    self._query = SyncQueryer(api_host=self._url, auth=self._auth, ip=ip, proxies=proxies)

  def get_balance(self, currency: str = "BTC"):
    assert currency, "currency must be not None and not empty!"

    method = "POST"
    path = "/info/balance"
    data = {
      "currency": currency
    }

    response = self._query.query(method=method, path=path, data=data)
    return response

  def get_order(
      self,
      order_currency: str,
      payment_currency: str = None,
      type: Type = None,
      order_id: str = None,
      count: int = 100,
      after: int = None,
    ):
    assert order_currency, "order_currency must be not None and not empty!"

    method = "POST"
    path = "/info/orders"
    data = {
      "order_currency": order_currency,
      "payment_currency": payment_currency,
      "type": type and type.value,
      "order_id": order_id,
      "count": count,
      "after": after,
    }

    response = self._query.query(method=method, path=path, data=data)
    return response

  def cancel_order(
      self,
      type: Type,
      order_id: str,
      order_currency: str,
      payment_currency: str,
    ):
    assert type, "type must be not None!"
    assert order_id, "order_id must be not None and not empty!"
    assert order_currency, "order_currency must be not None and not empty!"
    assert payment_currency, "payment_currency must be not None and not empty!"

    method = "POST"
    path = "/trade/cancel"
    data = {
      "type": type.value,
      "order_id": order_id,
      "order_currency": order_currency,
      "payment_currency": payment_currency,
    }

    response = self._query.query(method=method, path=path, data=data)
    return response

# https://apidocs.bithumb.com/

if __name__ == "__main__":
  key_path = sys.argv[1]
  mea = "Spot.Bithumb.v2"
  proxies={
    "http": "http://bithumb:rygTRMO2mJb0@54.180.70.49:31280",
    "https": "http://bithumb:rygTRMO2mJb0@54.180.70.49:31280"
  }
  client = BithumbPrivateClient(key_path, mea, None, proxies=None)
  resp = client.get_balance()
  # resp = client.get_order("BTC")
  # resp = client.cancel_order(Type.BID, "1234", "BTC", "KRW")
  print(json.dumps(resp.json(), indent=2))
